package com.bensonbasement.snorflux.client.states;

import com.bensonbasement.snorflux.client.SnorfluxClient;
import com.bensonbasement.snorflux.memory.RLevel;
import com.bensonbasement.snorflux.messages.fromserver.CommandRequestMessage;
import com.bensonbasement.snorflux.messages.fromserver.DeleteInfoMessage;
import com.bensonbasement.snorflux.messages.fromserver.InfoUpdateMessage;
import com.bensonbasement.snorflux.messages.fromserver.ReportMessage;
import com.bensonbasement.snorflux.messages.fromserver.VisibilityUpdateMessage;
import com.bensonbasement.snorflux.messages.fromserver.WorldTimeMessage;
import com.bensonbasement.snorflux.messages.fromserver.reports.Report;
import com.bensonbasement.snorflux.messages.fromserver.reports.WalkReport;
import com.bensonbasement.snorflux.utils.SpaceReference;

public class IdleState extends ConnectedState {
	
	public IdleState(SnorfluxClient client) {
		super(client);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void initialize() {
		super.initialize();
		getWorldUpdateManager().animationStop();
	}
	
	@Override
	public void handleWorldTimeMessage(WorldTimeMessage message) {
		if (message instanceof InfoUpdateMessage) {
			handleInfoUpdateMessage((InfoUpdateMessage)message);
		}
		else if (message instanceof DeleteInfoMessage) {
			handleDeleteInfoMessage((DeleteInfoMessage)message);
		}
		else if (message instanceof VisibilityUpdateMessage) {
			handleVisibilityUpdateMessage((VisibilityUpdateMessage)message);
		}
		else if (message instanceof CommandRequestMessage) {
			handleCommandRequestMessage((CommandRequestMessage)message);
		}
		else if (message instanceof ReportMessage) {
			handleReportMessage((ReportMessage)message);
		}
		else {
			throw new RuntimeException("Unknown message type: "+message.getClass().getCanonicalName());
		}
	}
	
	public void handleInfoUpdateMessage(InfoUpdateMessage message) {
		getMemory().updateInfo(message.getInfo());
	}
	
	public void handleDeleteInfoMessage(DeleteInfoMessage message) {
		getMemory().forgetEntity(message.getWorldElementID());
	}
	
	public void handleVisibilityUpdateMessage(VisibilityUpdateMessage message) {
		getMemory().updateVisibility(message.getNewlyVisibleSpaceIDs(), message.getNewlyNonVisibleSpaceIDs());
//		// TODO: This is a cheap hack.
//		if (getLevel() == null) {
//			Iterator<Long> iter = message.getNewlyVisibleSpaceIDs().iterator();
//			if (iter.hasNext()) {
//				RSpace space = (RSpace) getMemory().getWorld().getWorldElement(iter.next());
//				setLevel(space.getLevel());
//			}
//		}
	}
	
	public void handleCommandRequestMessage(CommandRequestMessage message) {
		changeState(new CommandSelectState(client,message));
	}
	
	public void handleReportMessage(ReportMessage message) {
		Report report = message.getReport();
		SpaceReference spaceOfInterest = report.getSpaceOfInterest();
		if (spaceOfInterest != null) {
			RLevel level = getMemory().getWorld().getLevel(spaceOfInterest.getLevel());
			// TODO: Make the MapPanel scroll to the right spot.
			setLevel(level);
		}
		if (report instanceof WalkReport) {
			WalkAnimationState newState = new WalkAnimationState(client, (WalkReport) report);
			changeState(newState);
		}
	}
}
